Lecture 6 notes

Here are some notes on lecture 6, focusing on differences between numpy and R...


In [2]:
# component-wise (vectorized) operations only work on numpy arrays, not on python lists.
x = array([1,2,3])
sqrt(x)


Out[2]:
array([ 1.        ,  1.41421356,  1.73205081])

In [3]:
# component-wise multiplication works as you may expect
cos(x) * sin(x)


Out[3]:
array([ 0.45464871, -0.37840125, -0.13970775])

In [7]:
# a particularly irritating point is that python uses "**" instead of "^" for exponentiation.
# "^" is bitwise XOR, so it'll give you an answer, but not the right one! 
x**2


Out[7]:
array([1, 4, 9])

In [8]:
x^2 # this doesn't do what you might expect!


Out[8]:
array([3, 0, 1])

In [10]:
# specifying data type manually. 
y = array([1,2,3], dtype = complex)
y


Out[10]:
array([ 1.+0.j,  2.+0.j,  3.+0.j])

In [11]:
A = array([[1.,2],[3,4],[5,6]])
A.shape


Out[11]:
(3, 2)

In [12]:
# transpose works like in R. 
# As in R, there's no difference between a row vector and a column vector;
# a 1D array is just a vector.
A.T


Out[12]:
array([[ 1.,  3.,  5.],
       [ 2.,  4.,  6.]])

In [19]:
# this function is only here because it's pretty. 
x = linspace(0., 3, 1000)
y = x**2 - 2.*cos(x**3)
plot(x,y)


Out[19]:
[<matplotlib.lines.Line2D at 0x10d6cb0d0>]

In [20]:
# you can make an array of ones of as many dimensions as desired.
# it takes a tuple as an argument.
A = ones((4,3,2))
A


Out[20]:
array([[[ 1.,  1.],
        [ 1.,  1.],
        [ 1.,  1.]],

       [[ 1.,  1.],
        [ 1.,  1.],
        [ 1.,  1.]],

       [[ 1.,  1.],
        [ 1.,  1.],
        [ 1.,  1.]],

       [[ 1.,  1.],
        [ 1.,  1.],
        [ 1.,  1.]]])

In [22]:
# in numpy, rank refers to the number of subscripts to index into it (number of dimensions)
rank(A)


Out[22]:
3

In [23]:
A[0,1,1]


Out[23]:
1.0

In [24]:
# solving linear systems of equations
A = array([[1.,2], [3,4]])
b = array([26., 60])
# solve Ax = b:
from numpy.linalg import solve
solve(A,b)


Out[24]:
array([ 8.,  9.])

Dear OSX,

You may have noticed that I never actually want to type "bumpy". Like, never, not once ever have I typed the word "bumpy" on this computer. So you can stop trying to auto-correct "numpy" now.

Thanks.


In [28]:
# here's an example of working with a function that returns 2 things as a tuple.
# give each one its own name to unpack it.
from numpy.linalg import eig
evals, evecs = eig(A)
evals


Out[28]:
array([-0.37228132,  5.37228132])

In [29]:
evecs


Out[29]:
array([[-0.82456484, -0.41597356],
       [ 0.56576746, -0.90937671]])

In [30]:
# quadrature (numerical integration) in scipy:
from scipy.integrate import quad
def f(x):
    return x**2
quad(f, 0., 2.) # function and endpoints; returns a value and an error estimate as a tuple.


Out[30]:
(2.666666666666667, 2.960594732333751e-14)

In [31]:
# lambda/anonymous functions 
quad(lambda x: x**2, 0., 2.)


Out[31]:
(2.666666666666667, 2.960594732333751e-14)

In [35]:
# running tests using __name__ == "__main__" vs. by importing and running
# import and run
import mysqrt
mysqrt.test()


testing x =    0.000000000000000
s = 0.000000000000000e+00, numpy sqrt = 0.000000000000000e+00
testing x =    2.000000000000000
s = 1.414213562373095e+00, numpy sqrt = 1.414213562373095e+00
testing x =  100.000000000000000
s = 1.000000000000000e+01, numpy sqrt = 1.000000000000000e+01
testing x = 10000.000000000000000
s = 1.000000000000000e+02, numpy sqrt = 1.000000000000000e+02
testing x =    0.000100000000000
s = 1.000000000000000e-02, numpy sqrt = 1.000000000000000e-02

In [36]:
mysqrt.__name__


Out[36]:
'mysqrt'

In [37]:
# or just run directly:
run mysqrt.py


running tests...
testing x =    0.000000000000000
s = 0.000000000000000e+00, numpy sqrt = 0.000000000000000e+00
testing x =    2.000000000000000
s = 1.414213562373095e+00, numpy sqrt = 1.414213562373095e+00
testing x =  100.000000000000000
s = 1.000000000000000e+01, numpy sqrt = 1.000000000000000e+01
testing x = 10000.000000000000000
s = 1.000000000000000e+02, numpy sqrt = 1.000000000000000e+02
testing x =    0.000100000000000
s = 1.000000000000000e-02, numpy sqrt = 1.000000000000000e-02

Timing things


In [56]:
time sqrt(2.) # this is a way to time a single thing.


CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
Wall time: 0.00 s
Out[56]:
1.4142135623730951

In [57]:
timeit sqrt(2.) # this is how to loop a bunch of time and average the results.


100000 loops, best of 3: 1.94 us per loop

In [51]:
timeit mysqrt.sqrt2(2.)


100000 loops, best of 3: 5.46 us per loop

In [53]:
timeit y = sqrt(linspace(0,1,1000)) # vectorized form is super fast, same as in R.


10000 loops, best of 3: 21.9 us per loop

This %%timeit keyword is specific to ipython notebook.


In [55]:
%%timeit
y = zeros(1000)
for i in range(1000): # looping manually is really slow, same as in R. 
    y[i] = sqrt(i)


100 loops, best of 3: 3.15 ms per loop

In [ ]: